package com.weixing.mall.provider.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.weixing.mall.base.constant.GlobalConstant;
import com.weixing.mall.base.enums.WhetherEnum;
import com.weixing.mall.base.exception.BusinessException;
import com.weixing.mall.base.utils.EnumUtil;
import com.weixing.mall.base.wrapper.Result;
import com.weixing.mall.core.enums.OrderAppTagEnum;
import com.weixing.mall.core.enums.OrderSysTagEnum;
import com.weixing.mall.core.support.auth.AuthUtil;
import com.weixing.mall.core.support.auth.SysAuth;
import com.weixing.mall.core.utils.CommonUtil;
import com.weixing.mall.provider.api.model.enums.OrderTypeEnum;
import com.weixing.mall.provider.api.model.vo.*;
import com.weixing.mall.provider.api.model.vo.dto.BillProductDto;
import com.weixing.mall.provider.api.model.vo.dto.BillSaveDto;
import com.weixing.mall.provider.api.model.vo.dto.DepotRPcVo;
import com.weixing.mall.provider.api.service.*;
import com.weixing.mall.provider.mapper.OrderExpressMapper;
import com.weixing.mall.provider.mapper.OrderMapper;
import com.weixing.mall.provider.mapper.OrderOperationMapper;
import com.weixing.mall.provider.model.domain.*;
import com.weixing.mall.provider.model.dto.*;
import com.weixing.mall.provider.model.enums.*;
import com.weixing.mall.provider.model.query.*;
import com.weixing.mall.provider.model.vo.*;
import com.weixing.mall.provider.model.vo.member.MemberOrderVo;
import com.weixing.mall.provider.service.*;
import com.weixing.mall.util.CommUtil;
import com.weixing.mall.util.ListUtil;
import com.weixing.mall.util.logistics.LogisticsQuery;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单模块-订单表 服务实现类
 * </p>
 *
 * @author Small
 * @since 2019-11-20
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {


    @Autowired
    private IOrderGoodsService orderGoodsService;
    @Autowired
    private OrderExpressMapper orderExpressMapper;
    @Autowired
    private AgentServiceRpc agentServiceRpc;
    @Autowired
    private OrderOperationMapper orderOperationMapper;

    @Autowired
    private ItemFeign itemFeign;

    @Autowired
    private SysUserRpcService userRpcService;

    @Autowired
    private IOrderPayService orderPayService;
    @Autowired
    private IOrderPrintService orderPrintService;
    @Autowired
    private IOrderOperationService orderOperationService;
    @Autowired
    private SysConfigServiceFeign sysConfigService;
    @Autowired
    private IAfterSaleService afterSaleService;
    @Autowired
    private IOrderBindingService orderBindingService;
    @Autowired
    private DepotServiceRpc depotServiceRpc;
    @Autowired
    private GoodsTransBillServiceRpc goodsTransBillServiceRpc;
    @Autowired
    private ProductStockServiceRpc productStockServiceRpc;
    @Autowired
    private IOrderAgentService orderAgentService;
    @Autowired
    private SysUserRpcService sysUserRpcService;
    @Autowired
    private SysDictRPC sysDictRPC;
    @Autowired
    private IOrderDeliverLogService orderDeliverLogService;

    @Override
    public OrderDetilVo selectOrderDetails(long orderId) {
        SysAuth sysAuth = AuthUtil.getSysExt();
        //订单基础信息
        OrderDetilVo vo = baseMapper.selectOrderDetails(orderId);
        String orderSn = vo.getOrderSn();
        if (vo == null) {
            return vo;
        }
        //订单商品信息
        OrderGoodsVo orderGoods = orderGoodsService.findByOrderId(orderId);
        if (orderGoods != null) {
            BeanUtils.copyProperties(orderGoods, vo);
        }
        //订单收货信息
        OrderExpressVo orderExpressVo = orderExpressMapper.selectByOrderId(orderId);
        if (orderExpressVo != null) {
            if (ObjectUtil.isNotEmpty(sysAuth) && sysAuth.isSensitive()) {//是不是数据敏感者
                orderExpressVo.setContactPhone(CommonUtil.coverMobile(orderExpressVo.getContactPhone()));
            }
            BeanUtils.copyProperties(orderExpressVo, vo);
        }
        //订单商品属性
        if (orderGoods == null) {
            return vo;
        }
        ItemVo itemVo = itemFeign.findById(orderGoods.getProductId()).getData();
        if (itemVo != null) {
            BeanUtils.copyProperties(itemVo, vo);
        }
        //订单支付信息
        OrderPay orderPay = orderPayService.findByOrderId(orderId);
        if (orderPay != null) {
            vo.setPayTime(orderPay.getPayTime());
        }
        List<OrderOperation> list = orderOperationMapper.selectByOrder(orderId);
        vo.setOperationList(list);
        //重新组合省市县
        vo.wrapArea();
        vo.setId(orderId);
        vo.setOrderSn(orderSn);
        // 订单上交款，需收款
        // 订单售后
        vo.wrapAfterSale(afterSaleService.selectByOrderId(orderId));
        return vo;
    }

    @Override
    public OrderDetilTimeVo selectOrderDetailsTime(long id) {
        return baseMapper.selectOrderDetailsTime(id);
    }

    @Override
    public void changeOrderStatus(ChgOrderStatusDto chgOrderStatusDto) {
        chgOrderStatusDto.setUpdatedTime(new Date());
        baseMapper.updateOrderStatus(chgOrderStatusDto);
    }

    @Override
    public void changeOrderPayStatus(ChgOrderPayStatusDto chgOrderPayStatusDto) {
        baseMapper.updateOrderPayStatus(chgOrderPayStatusDto);
    }


    @Override
    public void PushOrderSn(String[] ids) {
        orderPrintService.remove(new QueryWrapper<OrderPrint>().eq("1", 1));
        for (int i = 0; i < ids.length; i++) {
            baseMapper.PushOrderSn(Long.valueOf(ids[i]));
        }
        List<Order> orderList = list(new QueryWrapper<Order>().in("id", ids));
        List<OrderPrint> orderPrintList = Lists.newArrayList();
        for (Order order : orderList) {
            OrderPrint orderPrint = new OrderPrint();
            BeanUtils.copyProperties(order, orderPrint);
            orderPrint.setId(null);
            orderPrintList.add(orderPrint);
        }
        orderPrintService.saveBatch(orderPrintList, ListUtil.SIZE);
    }

    @Override
    public IPage selectUntyingList(OrderUntyingQuery orderUntyingQuery, Page initMpPage) {
        return baseMapper.selectUntyingList(initMpPage, orderUntyingQuery);
    }

    @Override
    public IPage selectDistributionShipperList(OrderPCQuery orderPCQuery, Page initMpPage) {
        List<Integer> list = Lists.newArrayList();
        if (ObjectUtil.isNotEmpty(orderPCQuery) && orderPCQuery.getOrderStatus() == null) {
            list.add(OrderStateEnum.SEALED.getValue());
            list.add(OrderStateEnum.WAIT_SHIP.getValue());
        } else {
            list.add(orderPCQuery.getOrderStatus().getValue());
        }
        orderPCQuery.setStatus(list);
        IPage<OrderListPCVo> orderListPCVoIPage = baseMapper.selectDistributionShipperList(initMpPage, orderPCQuery);
        List<OrderListPCVo> records = orderListPCVoIPage.getRecords();
        for (OrderListPCVo record : records) {
            OrderOperation orderOperation = orderOperationMapper.selectByOrderIdOperationTime(record.getId());
            if (orderOperation != null) {
                record.setOperationTime(orderOperation.getCreatedTime());
            }
        }
        return orderListPCVoIPage;
    }

    @Override
    public IPage<OrderListPCVo> selectDeliverOrderList(OrderPCQuery orderPCQuery, Page initMpPage) {
        IPage<OrderListPCVo> orderListPCVoIPage = baseMapper.selectDeliverOrderList(initMpPage, orderPCQuery);
        List<OrderListPCVo> records = orderListPCVoIPage.getRecords();
        for (OrderListPCVo record : records) {
            OrderOperation orderOperation = orderOperationMapper.selectByOrderIdOperationTime(record.getId());
            if (orderOperation != null) {
                record.setOperationTime(orderOperation.getCreatedTime());
            }
        }
        return orderListPCVoIPage;
    }

    @Override
    public StaticVo deliverOrderTotal(OrderPCQuery orderPCQuery){
        return baseMapper.deliverOrderTotal(orderPCQuery);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void distributionShipper(List<DistributionShipperDto> distributionShipperDtoList) {
        //判断逻辑变动这里先注释   流程改为先分配发货员在生成调拨单
        /*if (!checkDistribution(distributionShipperDtoList)) {
            throw new BusinessException("含未生成调拨单的订单不可分配发货员");
        }*/

        baseMapper.distributionShipper(distributionShipperDtoList);
        List<Long> listId = distributionShipperDtoList.stream().map(DistributionShipperDto::getOrderId).collect(Collectors.toList());
        if (listId.size() > 0) {
            orderGoodsService.updateGoodsTag(listId);
        }
    }


    @Override
    public void shipperChgDepot(ShipperChgInfoDto scid, Long uid) {
        //只做仓库变更
        //判断订单是否是已封单状态 并且是未生成调拨单状态  是就可以修改  不是 则不可以修改
        Order order = getById(scid.getId());
        if (ObjectUtil.isEmpty(order)) {
            throw new BusinessException("订单信息不存在，请刷新后重试");
        }
        if (!OrderStateEnum.SEALED.getValue().equals(order.getOrderStatus())) {
            throw new BusinessException("非已封单状态订单不可变更");
        }
        if (IsCreatedBillEnum.YES.getValue().equals(order.getIsCreatedBill())) {
            throw new BusinessException("已生成调拨单的订单不可变更");
        }
        Result<DepotRPcVo> depotResult = depotServiceRpc.getById(scid.getDepotId());
        if (!depotResult.isSuccess()) {
            throw new BusinessException("仓库RPC服务调用失败，请重试！");
        }
        if (ObjectUtil.isEmpty(depotResult.getData())) {
            throw new BusinessException("仓库信息不存在，请重试！");
        }
        order.setDepotId(depotResult.getData().getId());
        order.setDepotName(depotResult.getData().getDepotName());
        order.setDepotCode(depotResult.getData().getDepotCode());
        order.setUpdatedBy(uid);
        order.setUpdatedTime(new Date());
        updateById(order);
    }

    @Override
    public IPage goodsIdentification(GoodsIdentificationQuery goodsIdentificationQuery, Page initMpPage) {
        IPage<GoodsIdentificationVo> goodsIdentificationVoIPage = baseMapper.goodsIdentification(initMpPage, goodsIdentificationQuery);
        List<GoodsIdentificationVo> records = goodsIdentificationVoIPage.getRecords();
//        for (GoodsIdentificationVo record : records) {
//            record.setAuditTime(null);
//        }
        return goodsIdentificationVoIPage;
    }

    @Override
    public List<GoodsIdentificationVo> goodsIdentification(GoodsIdentificationQuery goodsIdentificationQuery) {
        List<GoodsIdentificationVo> records = baseMapper.goodsIdentification(goodsIdentificationQuery);
        /*for (GoodsIdentificationVo record : records) {//为什么要把审核时间设置null？
            record.setAuditTime(null);
        }*/
        return records;
    }


    @Override
    public IPage selectAgentClaimList(AgentClaimQuery agentClaimQuery, Page initMpPage) {
        IPage<AgentClaimVo> agentClaimVoIPage = baseMapper.selectAgentClaimList(initMpPage, agentClaimQuery);
        List<AgentClaimVo> records = agentClaimVoIPage.getRecords();
        for (AgentClaimVo record : records) {
            AgentPlaceOrderVo agentPlaceOrderVo = null;
            if (agentPlaceOrderVo != null) {
                record.setAuditTime(agentPlaceOrderVo.getAuditTime());
                if (agentPlaceOrderVo.getAuditor() != null) {
                    record.setAuditor(agentPlaceOrderVo.getAuditor());
                }
                if (agentPlaceOrderVo.getIsAgentAudit() == 0) {
                    if (agentPlaceOrderVo.getUnAuditor() != null) {
                        if (agentPlaceOrderVo.getIsAgentAudit() != null && agentPlaceOrderVo.getIsAgentAudit() == 0) {
                            if (agentPlaceOrderVo.getUnAuditor() != null) {
                                record.setUnAuditor(agentPlaceOrderVo.getUnAuditor());
                            }
                        }
                    }
                }

            }
        }
        return agentClaimVoIPage;
    }


    @Override
    public void customerChgOrder(CustomerChgOrderDto chgOrderDto, Long uid) {

        SysUserEditVo sysUserEditVo = sysConfigService.getUserById(uid).getData();

        //修改商品相关字段
        CustomerChgOrderGoodsDto chgOrderGoodsDto = new CustomerChgOrderGoodsDto();
        if (chgOrderDto.getHeight() != null || chgOrderDto.getWeight() != null || chgOrderDto.getProductId() != null || chgOrderDto.getProductSkuDesp() != null) {
            if (chgOrderDto.getHeight() != null) {
                chgOrderGoodsDto.setHeight(chgOrderDto.getHeight());
            }
            if (chgOrderDto.getWeight() != null) {
                chgOrderGoodsDto.setWeight(chgOrderDto.getWeight());
            }
            if (chgOrderDto.getProductId() != null) {
                chgOrderGoodsDto.setProductId(chgOrderDto.getProductId());
            }
            if (chgOrderDto.getProductSkuDesp() != null) {
                chgOrderGoodsDto.setSkuDesp(chgOrderDto.getProductSkuDesp());
            }
            chgOrderGoodsDto.setOrderId(chgOrderDto.getId());
            orderGoodsService.customerChgOrder(chgOrderGoodsDto);

        }
        //修改邮寄地址相关字段

        ChgOrderExpressDto chgOrderExpressDto = new ChgOrderExpressDto();

        String[] areaPath = chgOrderDto.getAreaPath();
        if (areaPath.length > 0) {
            chgOrderExpressDto.setProvince(areaPath[0]);
            chgOrderExpressDto.setCity(areaPath[1]);
            chgOrderExpressDto.setRegion(areaPath[2]);
            chgOrderExpressDto.setTown(areaPath[3]);
        }
        if (chgOrderDto.getContactUser() != null || chgOrderDto.getContactPhone() != null || chgOrderDto.getAddrDetail() != null) {
            if (chgOrderDto.getContactUser() != null) {
                chgOrderExpressDto.setContactUser(chgOrderDto.getContactUser());
            }
            if (chgOrderDto.getContactPhone() != null) {
                chgOrderExpressDto.setContactPhone(chgOrderDto.getContactPhone());
            }
            if (chgOrderDto.getAddrDetail() != null) {
                chgOrderExpressDto.setAddrDetail(chgOrderDto.getAddrDetail());
            }
            chgOrderExpressDto.setOrderId(chgOrderDto.getId());
            //修改收货地址
            orderExpressMapper.customerChgOrder(chgOrderExpressDto);
        }


        ChgKefuRemarkDto customerChgRemarkOrderDto = new ChgKefuRemarkDto();
        //订单id
        customerChgRemarkOrderDto.setId(chgOrderDto.getId());
        //客服备注
        customerChgRemarkOrderDto.setRemark(chgOrderDto.getCustomerRemark());
        //修改客服备注
        baseMapper.updateCustomerRemark(customerChgRemarkOrderDto);

        //客服操作记录
        OrderOperationDto orderOperationDto = new OrderOperationDto();
        //操作人类型为客服 2
        orderOperationDto.setOperatorType(OperateTypeEnum.EDIT);
        //操作人id
        orderOperationDto.setOperatorId(uid);
        if (sysUserEditVo != null) {
            //操作人
            orderOperationDto.setOperator(sysUserEditVo.getRealName());
        }
        //订单id
        orderOperationDto.setOrderId(customerChgRemarkOrderDto.getId());
        //操作备注
        orderOperationDto.setRemark(customerChgRemarkOrderDto.getRemark());
        //操作内容
        orderOperationDto.setOperation("客服修改订单信息");
        orderOperationService.save(orderOperationDto);
        Order order = new Order();
        order.setId(chgOrderDto.getId());
        order.setUpdatedTime(new Date());
        updateById(order);
    }

    @Override
    public IPage selectOutOfStockList(Page initMpPage, CustomerOrderQuery customerOrderQuery, Long uid) {
        SysAuth sysExt = AuthUtil.getSysExt();
        Long[] agentIds = null;
        if (ObjectUtil.isNotEmpty(customerOrderQuery) && customerOrderQuery.getAgentId() != null) {
            agentIds = agentIds(customerOrderQuery.getAgentId());
        }
        //断货商品
        customerOrderQuery.setItemStatus(ProductStatusEnum.STATUS6);
        IPage<OutOfStockCancelOrderVo> pageList = baseMapper.selectOutOfStockList(initMpPage, customerOrderQuery, agentIds);
        List<OutOfStockCancelOrderVo> records = pageList.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            for (OutOfStockCancelOrderVo orderVo : records) {
                orderVo.setContactPhone(sysExt.isSensitive() ? CommonUtil.coverMobile(orderVo.getContactPhone()) : orderVo.getContactPhone());
            }
        }
        return pageList;
    }

    @Override
    public StaticVo selectOutOfStockListTotal(CustomerOrderQuery query) {
        Long[] agentIds = null;
        if (ObjectUtil.isNotEmpty(query) && query.getAgentId() != null) {
            agentIds = agentIds(query.getAgentId());
        }
        //断货商品
        query.setItemStatus(ProductStatusEnum.STATUS6);
        return baseMapper.selectOutOfStockListTotal(query, agentIds);
    }


    @Override
    public HashMap<String, Object> selectKefuOrderList(Page initMpPage, FrontCustomerOrderQuery frontCustomerOrderQuery, Long uid) {
        HashMap<String, Object> map = new HashMap<>();
        HashMap<String, Object> tem = new HashMap<>();
        Double receivable = 0.0;
        Double upPayment = 0.0;
        Integer count = 0;
        Double orderAmount = 0.0;
        //查询登录人的角色
        Result<List<RoleVo>> roleById = userRpcService.getRoleById(uid);
        List<RoleVo> data = roleById.getData();
        for (RoleVo datum : data) {
            if (datum.getRoleCode().equals("customerInCharge")) {
                frontCustomerOrderQuery.setCustomerId(null);
                break;
            } else if (datum.getRoleCode().equals("service")) {//客服
                frontCustomerOrderQuery.setCustomerId(uid);
            }
        }
        //TODO 新增逻辑要求  客服查询秒杀时若客服下边没有代理商则不返回列表数据
        if (frontCustomerOrderQuery.getOrderType() != null && OrderTypeEnum.SECKILL.getValue().equals(frontCustomerOrderQuery.getOrderType().getValue()) && frontCustomerOrderQuery.getCustomerId() != null) {
            List<AgentCustomerVo> list = agentServiceRpc.selectByCustomerId(uid);
            if (list == null || list.isEmpty()) {
                return null;
            }
        }
        //根据新增要求 客服下边没有绑定代理商时在查询全部时将秒杀订单排除
        if (frontCustomerOrderQuery.getOrderType() == null) {
            frontCustomerOrderQuery.setAloneKeFuOrderType(OrderTypeEnum.SECKILL.getValue());
        }

        IPage<FrontCustomerOrderVo> frontCustomerOrderVoIPage = baseMapper.selectCustomerOrderList(initMpPage, frontCustomerOrderQuery);
        //TODO  以下逻辑不知道什么没对应到流程 暂时注释掉
        /*List<FrontCustomerOrderVo> list = baseMapper.selectCustomerOrderList(frontCustomerOrderQuery);
        for (FrontCustomerOrderVo frontCustomerOrderVo : list) {
            if (frontCustomerOrderVo.getOrderType().getValue().equals(OrderTypeEnum.AGENT.getValue())) {
                //根据订单ID查询已审核人的折扣信息
                Double discount = null;
                if (discount != null) {
                    double v = frontCustomerOrderVo.getOrderPrice() * discount * frontCustomerOrderVo.getActDiscount();
                    receivable += v;
                }
                //当前登录人的折扣
                Result<AgentRpcVo> agentEditVoResult = agentServiceRpc.selectByAgentId(uid);
                if (agentEditVoResult != null) {
                    if (agentEditVoResult.getData() != null) {
                        double v1 = agentEditVoResult.getData().getDiscount() * frontCustomerOrderVo.getOrderPrice() * frontCustomerOrderVo.getActDiscount();
                        upPayment += v1;
                    }
                }
            }
            orderAmount += frontCustomerOrderVo.getOrderPrice();
        }*/
        map.put("record", frontCustomerOrderVoIPage);
        //tem.put("orderQuantity", list.size());
        tem.put("orderAmount", orderAmount);
        tem.put("receivable", receivable);
        tem.put("upPayment", upPayment);
        map.put("whole", tem);
        return map;
    }

    @Override
    public FrontCustomerOrderDetailsVo selectFrontCustomerOrderDetails(Long id) {
        FrontCustomerOrderDetailsVo frontCustomerOrderDetailsVo = baseMapper.selectFrontCustomerOrderDetails(id);
        frontCustomerOrderDetailsVo.setAddress(frontCustomerOrderDetailsVo.getProvince() + frontCustomerOrderDetailsVo.getCity() + frontCustomerOrderDetailsVo.getRegion());
        return frontCustomerOrderDetailsVo;
    }

    /*
     * TODO 这个地方做查询优化
     *
     * */
    @Override
    public OrderShowVo selectOrderShowVo(OrderVoQuery orderVoQuery) {
        SysAuth sysAuth = AuthUtil.getSysExt();
        OrderShowVo orderShowVo = baseMapper.selectOrderShowVo(orderVoQuery);
        if (orderShowVo != null) {

            //操作时间
            OrderOperation orderOperation = orderOperationMapper.selectByOrderIdOperationTime(orderVoQuery.getId());
            if (orderOperation != null) {
                orderShowVo.setOperationTime(orderOperation.getCreatedTime());
            }
            orderShowVo.setAddrDetail(orderShowVo.getProvince() + orderShowVo.getCity() + orderShowVo.getRegion() + orderShowVo.getAddrDetail());
            //物流信息加载
            if (StrUtil.isNotEmpty(orderShowVo.getExpressSn())) {
                orderShowVo.setLogisticsInfo(LogisticsQuery.getLogistics(orderShowVo.getExpressSn()));
            }
            //加载原始物流信息
            if (StrUtil.isNotEmpty(orderShowVo.getBeforExpressSn())) {
                orderShowVo.setBeforLogisticsInfo(LogisticsQuery.getLogistics(orderShowVo.getBeforExpressSn()));
            }
            orderShowVo.setContactPhone(null != sysAuth && sysAuth.isSensitive() ? CommUtil.coverMobile(orderShowVo.getContactPhone()) : orderShowVo.getContactPhone());
        }


        return orderShowVo;
    }

    /**
     * 方法描述:  根据状态<待发货、待付款、已取消...>查询订单列表
     *
     * @param page
     * @param status
     * @param mid
     * @return java.util.List<com.weixing.mall.provider.model.vo.FrontOrderVo>
     * @Author Small
     * @Date 2020/1/10 14:19
     */
    @Override
    public Page<MemberOrderVo> selectListByFrontStatus(Page page, OrderFrontStateEnum status, Long mid) {
        IPage<Order> orderIPage = null;
        // 查询订单列表
        QueryWrapper<Order> wrapper = new QueryWrapper();
        wrapper.eq("buyer_id", mid)
                .eq("order_from", OrderFromEnum.MEMBER.getValue())
                .eq("is_del", WhetherEnum.NO.getValue());
        //如果为全部SQL不添加状态过滤条件
        if (!OrderFrontStateEnum.ALL.getValue().equals(status.getValue())) {
            wrapper.eq("front_order_status", status.getValue());
        }
        wrapper.orderByDesc("id");
        orderIPage = page(page, wrapper);
        List<Order> records = orderIPage.getRecords();
        List<MemberOrderVo> frontOrderVoList = Lists.newArrayList();
        MemberOrderVo frontOrderVo = null;
        if (null != records && !records.isEmpty()) {
            for (Order order : records) {
                frontOrderVo = new MemberOrderVo();
                if (OrderTypeEnum.NORMAL.getValue().equals(order.getOrderType())
                        && WhetherEnum.NO.getValue().equals(order.getIsPay())
                        && !OrderFrontStateEnum.CANCELD.getValue().equals(order.getFrontOrderStatus())) {
                    frontOrderVo.setCanEdit(WhetherEnum.YES.getValue());
                }
                frontOrderVo.setOrderId(order.getId());
                frontOrderVo.setOrderSn(order.getOrderSn());
                frontOrderVo.setFrontOrderStatus(EnumUtil.getIEnum(OrderFrontStateEnum.class, order.getFrontOrderStatus()));
                frontOrderVo.setOrderPrice(order.getOrderPrice());
                frontOrderVo.setActualPrice(order.getActualPrice());
                List<FrontOrderGoodsVo> orderGoodss = orderGoodsService.selectFrontOrderGoodsVoByOrderId(order.getId());
                frontOrderVo.setOrderGoods(orderGoodss);
                frontOrderVoList.add(frontOrderVo);
            }
        }
        Page<MemberOrderVo> orderVoPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        orderVoPage.setRecords(frontOrderVoList);
        return orderVoPage;
    }

    @Override
    public IPage<MemberOrderVo> seachOrderList(Page page, OrderSeachQuery query) {
        return baseMapper.seachOrderList(page, query);
    }


    @Override
    public void changeFrontOrderStatus(ChgFrontOrderStatusDto chgFrontOrderStatusDto) {
        baseMapper.updateFrontOrderStatus(chgFrontOrderStatusDto);
    }

    @Override
    public IPage unshippedOrder(ShipperOrderQuery shipperOrderQuery, Page
            initMpPage, Long uid) {
        shipperOrderQuery.setShipperId(uid);
        IPage<FrontShipperUnshippedOrderVo> frontShipperUnshippedOrderVoIPage = baseMapper.unshippedOrder(initMpPage, shipperOrderQuery);
        List<FrontShipperUnshippedOrderVo> records = frontShipperUnshippedOrderVoIPage.getRecords();
        for (FrontShipperUnshippedOrderVo record : records) {
            OrderOperation orderOperation = orderOperationMapper.selectByOrderIdOperationTime(record.getId());
            if (orderOperation != null) {
                record.setOperationTime(orderOperation.getCreatedTime());
            }

        }
        return frontShipperUnshippedOrderVoIPage;
    }

    @Override
    public IPage deliverOrderList(ShipperOrderQuery shipperOrderQuery, Page initMpPage, Long uid) {
        shipperOrderQuery.setShipperId(uid);
        IPage<FrontShipperUnshippedOrderVo> frontShipperUnshippedOrderVoIPage = baseMapper.deliverOrderList(initMpPage, shipperOrderQuery);
        List<FrontShipperUnshippedOrderVo> records = frontShipperUnshippedOrderVoIPage.getRecords();
        for (FrontShipperUnshippedOrderVo record : records) {
            OrderOperation orderOperation = orderOperationMapper.selectByOrderIdOperationTime(record.getId());
            if (orderOperation != null) {
                record.setOperationTime(orderOperation.getCreatedTime());
            }

        }
        return frontShipperUnshippedOrderVoIPage;
    }

    @Override
    public void updateGoodsStatus(FrontShipperUpdateGoodsStatusDto
                                          fsugsd) {
        Order order = getById(fsugsd.getOrderId());
        if (ObjectUtil.isEmpty(order)) {
            throw new BusinessException("订单信息不存在！");
        }
        if (!order.getOrderStatus().equals(OrderStateEnum.WAIT_SHIP.getValue())) {
            throw new BusinessException("非待发货订单，保存信息失败！");
        }
        Integer sysTag = null;
        Integer appTag = null;
        if (ProductStatusEnum.STATUS7.getValue().equals(fsugsd.getProductStatus().getValue())) {//取消
            fsugsd.setOrderStatus(OrderStateEnum.CANCELD);
            fsugsd.setOrderFrontState(OrderFrontStateEnum.CANCELD);
            fsugsd.setCanceledTime(new DateTime());

            sysTag = OrderSysTagEnum.QXF_TAG_307.getValue();
            appTag = OrderAppTagEnum.QXF_TAG_305.getValue();
        } else if (ProductStatusEnum.STATUS6.getValue().equals(fsugsd.getProductStatus().getValue())) {//断货
            fsugsd.setOrderStatus(OrderStateEnum.CANCELD);
            fsugsd.setOrderFrontState(OrderFrontStateEnum.CANCELD);
            fsugsd.setCanceledTime(new DateTime());

            sysTag = OrderSysTagEnum.DHF_TAG_306.getValue();
            appTag = OrderAppTagEnum.DHF_TAG_304.getValue();
        } else if (ProductStatusEnum.STATUS1.getValue().equals(fsugsd.getProductStatus().getValue())) {//待定
            fsugsd.setWaitConfirmTime(new DateTime());

            sysTag = OrderSysTagEnum.DD_TAG_301.getValue();
            appTag = OrderAppTagEnum.DD_TAG_301.getValue();
        } else if (ProductStatusEnum.STATUS2.getValue().equals(fsugsd.getProductStatus().getValue())) {//待货
            fsugsd.setWaitGoodsTime(new DateTime());

            sysTag = OrderSysTagEnum.DH_TAG_302.getValue();
            appTag = OrderAppTagEnum.DH_TAG_302.getValue();
        } else if (ProductStatusEnum.STATUS5.getValue().equals(fsugsd.getProductStatus().getValue())) {//内部换货
            //Order order = getById(fsugsd.getOrderId());
            if (ObjectUtil.isNotEmpty(order) && order.getMatchProductId() != null) {//将匹配到的商品sku存入ordergoods
                Result<ItemVo> itemVoResult = itemFeign.findById(order.getMatchProductId());
                if (itemVoResult.isSuccess() && itemVoResult.getData() != null) {
                    fsugsd.setChgProductSkuDesp(itemVoResult.getData().getProductSkuDesp());
                }
            }

            sysTag = OrderSysTagEnum.ZHH_TAG_305.getValue();
            appTag = OrderAppTagEnum.DFH_TAG_106.getValue();
        } else if (ProductStatusEnum.STATUS3.getValue().equals(fsugsd.getProductStatus().getValue())) {//有现货
            sysTag = OrderSysTagEnum.YXH_TAG_303.getValue();
            appTag = OrderAppTagEnum.YXH_TAG_303.getValue();
        } else if (ProductStatusEnum.STATUS4.getValue().equals(fsugsd.getProductStatus().getValue())) {//需外采
            sysTag = OrderSysTagEnum.YXH1_TAG_304.getValue();
            appTag = OrderAppTagEnum.DFH_TAG_106.getValue();
        } else if (ProductStatusEnum.STATUS8.getValue().equals(fsugsd.getProductStatus().getValue())) {//待处理
            sysTag = OrderSysTagEnum.DCL_TAG_308.getValue();
            appTag = OrderAppTagEnum.DCL_TAG_306.getValue();
        }
        //同步售后货品状态
        synchState(fsugsd.getOrderId(), fsugsd.getProductStatus().getValue(), false);
        fsugsd.setUpdateTime(new Date());
        baseMapper.updateGoodsStatus(fsugsd);
        //同步订单标签
        updateTag(fsugsd.getOrderId(), sysTag, appTag);
    }

    private void synchState(Long orderId, Integer productStatus, boolean isFinished) {
        if (orderId != null) {
            if (isFinished) {
                afterSaleService.update(new LambdaUpdateWrapper<AfterSale>()
                        .set(AfterSale::getStatus, AfterSaleAuditEnum.FINISHED.getValue()).eq(AfterSale::getOrderId, orderId));
            } else {
                afterSaleService.update(new LambdaUpdateWrapper<AfterSale>().set(AfterSale::getItemStatus, productStatus)
                        .eq(AfterSale::getOrderId, orderId));
            }
        }
    }

    /**
     * 发货出入库单逻辑
     * 一、如果发货的为外采，则外采仓库生成一条入库单据，同时生成一条出库单据。
     * 二、如果为内部换货发货，则发货仓库（调拨的入库 ）出入口流程为：先出库匹配到的货品，然后入一个客户购买的商品货品，同时在出一个商品购买的货品。例如：订单里面为白色，XXL，匹配到的是黑色，XXL，则先出库的为黑色XXLl，同时在入一个白色，XXL。同时在出一个白色，XXL
     * 三、正常发货生成对应仓库出库单
     * <p>
     * 新增逻辑 在选择有货的时候需要判断仓库是否有库存  有库存则可以发货  没有则禁止发货 （外采仓除外）
     * <p>
     * 外采仓这条件暂时不考虑 所有仓一致 因为外采仓是选择需外的 不是选择有现货的   否则是操作上的问题
     * <p>
     * 再次按客户要求修改逻辑
     * 内部换货的出库和入库流程，统一使用发货仓库，不使用订单里面所匹配修改的仓库。发货部使用发货仓库，APP仓库发货使用APP仓库。写死，这个和客户确认过的内容
     *
     * @param orderId
     * @param auth
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmShipments(Long orderId, SysAuth auth, String depotSn, String expressSn) {
        Order order = getById(orderId);
        if (ObjectUtil.isEmpty(order)) {
            throw new BusinessException("订单不存在，发货失败！");
        }
        /*if ((order.getIsCreatedBill() == null || order.getIsCreatedBill() != 1)) {// 没生成调拨单不可发货
            throw new BusinessException("订单未生成调拨单，不可操作发货！");
        }*/
        List<Integer> list = Lists.newArrayList();
        list.add(ProductStatusEnum.STATUS3.getValue());
        list.add(ProductStatusEnum.STATUS4.getValue());
        list.add(ProductStatusEnum.STATUS5.getValue());

        if (!list.contains(order.getItemStatus())) {
            throw new BusinessException("订单货品状态不可操作发货！");
        }

        if (!OrderStateEnum.WAIT_SHIP.getValue().equals(order.getOrderStatus())) {
            throw new BusinessException("订单状态不可操作发货！");
        }

        //是否删除仓库扩展表记录标记参数
        boolean del_flag = false;
        Long del_depotId = null;
        Long del_productId = null;

        if (ProductStatusEnum.STATUS3.getValue().equals(order.getItemStatus())) {//若选择有现货 则判断是否有库存
            OrderGoodsVo orderGoodsVo = orderGoodsService.findByOrderId(order.getId());
            //查询仓库  根据角色不同，查询的匹配仓库不同
            Long depotId = 0L;
            if (auth.getUr().contains(GlobalConstant.RoleCode.SHIPPING)) {
                Result<DepotRPcVo> outVo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.FHB);
                if (outVo.isSuccess() && ObjectUtil.isNotEmpty(outVo.getData())) {
                    depotId = outVo.getData().getId();
                }
            } else if (auth.getUr().contains(GlobalConstant.RoleCode.APPYG)) {
                Result<DepotRPcVo> outVo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.APP);
                if (outVo.isSuccess() && ObjectUtil.isNotEmpty(outVo.getData())) {
                    depotId = outVo.getData().getId();
                }
                //2020-8-20 19:00:45 客户新增需求 只有在APP有现货时执行删除仓库扩展表记录 原因不详
                del_flag = true;
                del_depotId = depotId;
                del_productId = orderGoodsVo.getProductId();
            }
            Result<Integer> result = productStockServiceRpc.getByGoodsInfo(depotId, orderGoodsVo.getGoodsId(), orderGoodsVo.getProductId());
            if (result == null || !result.isSuccess()) {
                throw new BusinessException("仓库服务繁忙，请重试！");
            }
            if (result.getData() <= 0) {
                throw new BusinessException("仓库库存不足，发货失败！");
            }
        }
        //计算当前发货员提成
        order.setShipperCommission(calculateReward(auth.getUid()));
        order.setOrderStatus(OrderStateEnum.SHIPED.getValue());
        order.setFrontOrderStatus(OrderFrontStateEnum.WAIT_RECEIVE.getValue());
        order.setShipTime(DateTime.now());
        order.setExpressSn(expressSn);
        updateById(order);

        //同步售后审核主状态已完成
        synchState(orderId, order.getItemStatus(), true);

        //处理发货订单出入库
        handleOrderInOrOutDepot(order, auth);

        //同步订单标签值
        updateTag(orderId, OrderSysTagEnum.YFH_TAG_109.getValue(), OrderAppTagEnum.YFH_TAG_107.getValue());

        //RPC调用执行根据条件删除仓库扩展表记录
        if (del_flag && del_depotId != null && del_productId != null && ObjectUtil.isNotEmpty(depotSn)) {
            depotServiceRpc.delByCondition(del_depotId, del_productId, depotSn);
        }
        //记录发货员操作log
        orderDeliverLogService.addOrderDeliverLog(orderId, auth.getUid());
    }

    //处理订单出入库
    private void handleOrderInOrOutDepot(Order order, SysAuth auth) {
        // 商品状态需外采 生成一条入库单和出库单
        // 商品状态内部换货 将匹配的productId做出库 --》 入库客户购买的商品 --》再出库客户购买的产品
        // 商品有现货 正常生成出库单
        OrderGoodsVo orderGoodsVo = orderGoodsService.findByOrderId(order.getId());
        // productStockServiceRpc.inOutStock方法 调用参数说明：depotId出入库的Id号，productId 商品ID， flag 为2代表出库，flag为1代表入库。uid 系统当前操作人员
        if (ProductStatusEnum.STATUS4.getValue().equals(order.getItemStatus()) && ObjectUtil.isNotEmpty(orderGoodsVo)) {//外采
            //生成入库单
          /*  productStockServiceRpc.inOutStock(order.getDepotId(), orderGoodsVo.getProductId(), 1, auth.getUid(),order.getStockSn());
            //生成出库单
            productStockServiceRpc.inOutStock(order.getDepotId(), orderGoodsVo.getProductId(), 2, auth.getUid(),order.getStockSn());*/
        } else if (ProductStatusEnum.STATUS5.getValue().equals(order.getItemStatus()) && ObjectUtil.isNotEmpty(orderGoodsVo)) {//内换
            //再次新增逻辑判断2020年6月30日 也是和客户确认过 -_-||   角色为APP仓时用APP发货   角色为发货部时用发货部仓发货
            Long depotId = order.getDepotId();
            if (auth.getUr().contains(GlobalConstant.RoleCode.SHIPPING)) {
                Result<DepotRPcVo> outVo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.FHB);
                if (outVo.isSuccess() && ObjectUtil.isNotEmpty(outVo.getData())) {
                    depotId = outVo.getData().getId();
                }
            } else if (auth.getUr().contains(GlobalConstant.RoleCode.APPYG)) {
                Result<DepotRPcVo> outVo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.APP);
                if (outVo.isSuccess() && ObjectUtil.isNotEmpty(outVo.getData())) {
                    depotId = outVo.getData().getId();
                }
            }
            //内部换货出货之前判定下模糊匹配的仓库是否到仓库，如果没有拿货不允许发货。
            Result<Integer> result = productStockServiceRpc.getByGoodsInfo(depotId, orderGoodsVo.getGoodsId(), order.getMatchProductId());
            if (result == null || !result.isSuccess()) {
                throw new BusinessException("仓库服务繁忙，请重试！");
            }
            if (result.getData() <= 0) {
                throw new BusinessException("仓库库存不足，发货失败！");
            }
            //生成出库单 --- 商品为订单匹配的模糊商品
            productStockServiceRpc.inOutStock(depotId, order.getMatchProductId(), 2, auth.getUid(), order.getStockSn());
         /*   //生成入库单 --- 下单的商品
            productStockServiceRpc.inOutStock(depotId, orderGoodsVo.getProductId(), 1, auth.getUid(),order.getStockSn());
            //生成出库单 --- 下单的商品
            productStockServiceRpc.inOutStock(depotId, orderGoodsVo.getProductId(), 2, auth.getUid(),order.getStockSn());*/
        } else if (ProductStatusEnum.STATUS3.getValue().equals(order.getItemStatus()) && ObjectUtil.isNotEmpty(orderGoodsVo)) {//现货
            //生成出库单，
            Long depotId = order.getDepotId();
            if (auth.getUr().contains(GlobalConstant.RoleCode.SHIPPING)) {
                Result<DepotRPcVo> outVo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.FHB);
                if (outVo.isSuccess() && ObjectUtil.isNotEmpty(outVo.getData())) {
                    depotId = outVo.getData().getId();
                }
            } else if (auth.getUr().contains(GlobalConstant.RoleCode.APPYG)) {
                Result<DepotRPcVo> outVo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.APP);
                if (outVo.isSuccess() && ObjectUtil.isNotEmpty(outVo.getData())) {
                    depotId = outVo.getData().getId();
                }
            }
            productStockServiceRpc.inOutStock(depotId, orderGoodsVo.getProductId(), 2, auth.getUid(), order.getStockSn());
        }

    }

    //ReentrantLock lock = new ReentrantLock(true);

    //计算发货员提成
    public BigDecimal calculateReward(Long uid) {
        BigDecimal amount = BigDecimal.ZERO;
        Result<SysUserVo> result = sysUserRpcService.getById(uid);
        String code = "startReward";
        if (ObjectUtil.isNotEmpty(result)
                && result.isSuccess()
                && ObjectUtil.isNotEmpty(result.getData())) {
            SysUserVo sysUserVo = result.getData();
            Result<List<SysDictVo>> result2 = sysDictRPC.getDictByCode(code + sysUserVo.getUserStar());
            if (ObjectUtil.isNotEmpty(result2) && result2.isSuccess() && result2.getData() != null) {
                for (SysDictVo sdv : result2.getData()) {
                    amount = new BigDecimal(sdv.getDictValue());
                }
            }
        }
        return amount;
    }

    @Override
    public ScanCodeGoodsDetilVo selectScanCodeGoodsDetails
            (ScanCodeGoodsDetilQuery scanCodeGoodsDetilQuery) {
        SysAuth sysExt = AuthUtil.getSysExt();
        String commodityCode = commodityCodeOrProductSn(scanCodeGoodsDetilQuery.getQrCodeValue(), 0);
        if (StrUtil.isEmpty(commodityCode)) {
            return null;
        }
        String orderSn = orderBindingService.findOrderSnByCommodityCode(commodityCode);
        if (StrUtil.isEmpty(orderSn)) {
            return null;
        }
        scanCodeGoodsDetilQuery.setOrderSn(orderSn);
        ScanCodeGoodsDetilVo scgd = baseMapper.selectScanCodeGoodsDetil(scanCodeGoodsDetilQuery);
        scgd.setContactPhone(sysExt.isSensitive() ? CommUtil.coverMobile(scgd.getContactPhone()) : scgd.getContactPhone());
        return scgd;
    }

    @Override
    public ScanCodeGoodsDetilVo selectScanCodeGoodsDetails(String qrCodeValue) {
        SysAuth sysAuth = AuthUtil.getSysExt();
        String productSn = commodityCodeOrProductSn(qrCodeValue, 1);
        Result<ItemVo> itemVoResult = itemFeign.findProductVoByProductSn(productSn);
        ScanCodeGoodsDetilVo scgdv = new ScanCodeGoodsDetilVo();
        if (itemVoResult.isSuccess() && itemVoResult.getData() != null) {
            ItemVo itemVo = itemVoResult.getData();
            scgdv.setGoodsSn(itemVo.getGoodsSn());
            scgdv.setCostPrice(itemVo.getCostPrice());
            scgdv.setProductImg(itemVo.getProductImg());
            scgdv.setProductName(itemVo.getProductName());
            scgdv.setProductSkuDesp(itemVo.getProductSkuDesp());
            scgdv.setSupplierName(itemVo.getSupplierName());
        }
        scgdv.setContactPhone(sysAuth.isSensitive() ? CommUtil.coverMobile(scgdv.getContactPhone()) : scgdv.getContactPhone());
        return scgdv;
    }

    @Override
    public ScanCodeAfterSaleVo selectScanCodeReceiveDetails
            (ScanCodeGoodsDetilQuery scanCodeGoodsDetilQuery) {
        String commodityCode = commodityCodeOrProductSn(scanCodeGoodsDetilQuery.getQrCodeValue(), 0);
        if (StrUtil.isEmpty(commodityCode)) {
            return null;
        }
        String orderSn = orderBindingService.findOrderSnByCommodityCode(commodityCode);
        if (StrUtil.isEmpty(orderSn)) {
            return null;
        }
        scanCodeGoodsDetilQuery.setOrderSn(orderSn);
        return baseMapper.selectScanCodeReceiveDetil(scanCodeGoodsDetilQuery);
    }

    private String commodityCodeOrProductSn(String qrCodeValue, int i) {//i 只能是 0 (commodityCode)或 1 (ProductSn)
        if (StrUtil.isNotEmpty(qrCodeValue)) {
            int index = qrCodeValue.lastIndexOf("/");
            if (qrCodeValue.length() <= index) {
                return "";
            }
            String qrCode = qrCodeValue.substring(index + 1);
            String[] codeArray = qrCode.split("_");
            return codeArray.length > i ? codeArray[i] : "";
        }
        return "";
    }

    @Override
    public OrderTypeEnum selectByAgentSn(String orderSn) {
        Order order = baseMapper.selectOne(new QueryWrapper<Order>().eq("order_sn", orderSn));
        Integer orderType = order.getOrderType();
        OrderTypeEnum orderTypeEnum = null;
        orderTypeEnum = OrderTypeEnum.values()[order.getOrderType()];
        return orderTypeEnum;
    }

    /**
     * 历史订单
     *
     * @param initMpPage
     * @param orderQuery
     * @return
     */
    @Override
    public IPage historyOrder(Page initMpPage, OrderPCQuery orderQuery) {
        DepotRPcVo vo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.OUT).getData();
        if (vo != null) {
            orderQuery.setOutDepotId(vo.getId());
        }
        IPage<OrderListPCVo> iPage = baseMapper.historyOrder(initMpPage, orderQuery);
        return iPage;
    }

    @Override
    public IPage historyOrder2(Page initMpPage, OrderPCQuery orderQuery) {
        DepotRPcVo vo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.OUT).getData();
        if (vo != null) {
            orderQuery.setOutDepotId(vo.getId());
        }
        IPage<OrderListPCVo> iPage = baseMapper.sealedBillOrder(initMpPage, orderQuery);
        return iPage;
    }

    private BillSaveDto checkProduct(OrderGoods orderGoods, Map<Long, BillSaveDto> transMap) {
        for (Map.Entry<Long, BillSaveDto> entry : transMap.entrySet()) {
            BillSaveDto stockVoList = entry.getValue();
            List<BillProductDto> tt = stockVoList.getProductIds();
            for (BillProductDto billProductDto : tt) {
                if (billProductDto.getProductId().equals(orderGoods.getProductId()) || billProductDto.getGoodsId().equals(orderGoods.getGoodsId())) {
                    return stockVoList;
                }
            }
        }
        return null;
    }


    @Override
    public IPage<SealingSheetOrderVo> sealingSheetOrderList(Page
                                                                    initMpPage, SealingSheetOrderQuery sealingSheetOrderQuery) {
        //return baseMapper.sealingSheetOrderList(initMpPage, sealingSheetOrderQuery, OrderStateEnum.SEALED.getValue(), IsCreatedBillEnum.YES.getValue());
        return baseMapper.sealingSheetOrderList(initMpPage, sealingSheetOrderQuery, OrderStateEnum.WAIT_SHIP.getValue(), IsCreatedBillEnum.YES.getValue());
    }

    @Override
    public List<SealingSheetOrderVo> sealingSheetOrderList() {
        return baseMapper.sealingSheetOrderLists(OrderStateEnum.HAS_PAY.getValue());
    }

    @Override
    public void updateSealingSheetOrder(Long orderId, Long depotId, String
            depotName) {
        Order order = new Order();
        order.setId(orderId);
        order.setDepotId(depotId);
        order.setDepotName(depotName);
        order.setUpdatedTime(new Date());
        updateById(order);
    }

    /**
     * 生成调拨单
     * 规则：一、如果为精准匹配到仓库的订单，则将匹配到的仓库向目标仓库（发货仓）生成调拨单。
     * 二、如果为模糊匹配到的仓库订单，则将匹配到的仓库向目标仓库（发货仓）生成调拨单。
     * 三、如果订单匹配的是外采仓库，则不执行调拨操作。
     * 四、如果订单匹配的仓库和所选的仓库是同一个仓库，则不执行调拨操作
     *
     * @param orderIds
     * @param depotId
     * @param depotName
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createBillTrands(String orderIds, Long depotId, String depotName, Long uid) {
        if (StrUtil.isEmpty(orderIds)) {


            return "未选中订单";
        }
        if (depotId == null) {

            return "未选中仓库";
        }
        String[] orderIdsArray = orderIds.split(",");
        //新增发货员名称获取第一个 讨论说客户自己认为选中的订单都是同一个发货员
        String shipperName = "";
        //新增调整逻辑先分配发货员才可以生成订单
        List<Order> orderList = list(new LambdaQueryWrapper<Order>().in(Order::getId, orderIdsArray));
        List<Long> shipIdList = orderList.stream().map(Order::getShipperId).distinct().collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(shipIdList) && shipIdList.size() > 1) {

            return "调拨单存在不同的发货员";
        }
        for (Order o : orderList) {
            if (ObjectUtil.isEmpty(o) || o.getShipperId() == null) {

                return "有未分配发货员的订单不可进行生成调拨单操作";
            }
            if (StrUtil.isEmpty(shipperName)) {
                shipperName = o.getShipperName();
            }
        }

        Long outDepotId = null;
        Result<DepotRPcVo> outVo = depotServiceRpc.getBycode(GlobalConstant.DepotCode.OUT);
        if (outVo.isSuccess() && ObjectUtil.isNotEmpty(outVo.getData())) {
            outDepotId = outVo.getData().getId();
        }

        //查询选中的订单信息
        List<OrderBillInfoVo> list = baseMapper.selectOrderBillInfoList(orderIdsArray, IsCreatedBillEnum.YES.getValue());

        //过滤  匹配的仓库和所选的仓库是同一个仓库的订单
        list.removeIf(orderBillInfoVo -> depotId.equals(orderBillInfoVo.getDepotId()));
        //过滤  匹配的是外采仓库的订单
        if (outDepotId != null && list.size() > 0) {
            Iterator<OrderBillInfoVo> it = list.iterator();
            while (it.hasNext()) {
                if (outDepotId.equals(it.next().getDepotId())) {
                    it.remove();
                }
            }
        }
        List<Long> idList = list.stream().map(OrderBillInfoVo::getDepotId).collect(Collectors.toList());
        idList = idList.stream().distinct().collect(Collectors.toList());
       /* if (idList.size() != 1) {
            throw new BusinessException("生成调拨单的匹配仓库不一致，请重新选择");
        }*/
        if (list.size() > 0) {
            //封装订单为同一出库Id的List  TODO 这块逻辑不对，需要调整
            List<BillProductDto> bsdList = Lists.newArrayList();
            BillSaveDto billSaveDto = new BillSaveDto();
            billSaveDto.setInDepotId(depotId);
            billSaveDto.setOutDepotId(idList.get(0));
            billSaveDto.setBillNum(list.size());
            billSaveDto.setRemark(shipperName);
            billSaveDto.setShipperName(shipperName);
            billSaveDto.setShipperId(shipIdList.get(0));
            billSaveDto.setUid(uid);
            for (OrderBillInfoVo obiv : list) {
                //Long productId=obiv.getProductId();
                //Long goodsId=obiv.getGoodsId();
                Long productId = obiv.getMatchProductId();
                Long goodsId = obiv.getMatchGoodsId();
                boolean falg = false;
                for (BillProductDto bp : bsdList) {
                    Long bpProductId = bp.getProductId();
                    if (bpProductId.longValue() == productId.longValue()) {//如果已经在入库单据，则调拨数量价加1
                        bp.setStock(bp.getStock() + 1);
                        falg = true;
                    }
                }
                if (!falg) {//
                    BillProductDto dto = new BillProductDto();
                    dto.setStock(1);
                    dto.setProductId(productId);
                    dto.setGoodsId(goodsId);
                    dto.setStockSn(obiv.getStockSn());
                    dto.setStockId(obiv.getStockId());
                    dto.setOrderSn(obiv.getOrderSn());
                    dto.setFl(obiv.getFl());
                    dto.setOrderType(obiv.getOrderType().getDesp());
                    bsdList.add(dto);
                }

                /*if (bsdList.size() > 0) {
                    //是否存在标记  true 需要新增  false  不需要新增
                    boolean flag = true;
                    for (BillSaveDto bsd : bsdList) {
                        if (bsd.getOutDepotId().equals(obiv.getDepotId())) {//已存在 增加数据
                            BillProductDto billProductDto = new BillProductDto();
                            billProductDto.setStock(1);
                            billProductDto.setGoodsId(obiv.getGoodsId());
                            billProductDto.setProductId(obiv.getProductId());
                            bsd.getProductIds().add(billProductDto);
                            bsd.setBillNum(bsd.getProductIds().size());
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {//新增
                        bsdList.add(createBillSaveDto(obiv, depotId, depotName, uid, shipperName));
                    }
                } else {//新增
                    bsdList.add(createBillSaveDto(obiv, depotId, depotName, uid, shipperName));
                }*/
            }
            billSaveDto.setProductIds(bsdList);
            Result result = goodsTransBillServiceRpc.goodstransbill(billSaveDto);
           /* if (!result.isSuccess()) {
                throw new BusinessException("调拨失败，稍后在试");
            }*/
           /* //封装循环数据生成调拨单
            bsdList.forEach(billSaveDto -> {

            });*/
            //批量更新订单仓库数据
            List<Order> updateBatchOrderlist = Lists.newArrayList();
            list.forEach(orderBillInfoVo -> {
                Order order = new Order();
                order.setId(orderBillInfoVo.getId());
                order.setUpdatedTime(new Date());
                /*order.setDepotId(depotId);
                order.setDepotName(depotName);*/
                order.setIsCreatedBill(IsCreatedBillEnum.YES.getValue());
                updateBatchOrderlist.add(order);
            });
            updateBatchById(updateBatchOrderlist, ListUtil.SIZE);
        }
        return null;
    }

    //封装BillSaveDto数据
    private BillSaveDto createBillSaveDto(OrderBillInfoVo obiv, Long depotId, String depotName, Long uid, String shipperName) {
        List<BillProductDto> productList = Lists.newArrayList();
        BillProductDto billProductDto = new BillProductDto();
        billProductDto.setStock(1);
        billProductDto.setGoodsId(obiv.getGoodsId());
        billProductDto.setProductId(obiv.getProductId());
        productList.add(billProductDto);

        BillSaveDto billSaveDto = new BillSaveDto();
        billSaveDto.setOutDepotId(obiv.getDepotId());
        billSaveDto.setBillNum(productList.size());
        billSaveDto.setInDepotId(depotId);
        billSaveDto.setDepotName(depotName);
        billSaveDto.setUid(uid);
        billSaveDto.setProductIds(productList);
        billSaveDto.setRemark(shipperName);
        return billSaveDto;
    }


    private Long[] agentIds(Long agentId) {
        Long[] agentIds = null;
        agentIds = agentServiceRpc.selectAgentTreeByParentId(agentId);
        if (agentIds != null) {
            List<Long> list = new ArrayList<>(Arrays.asList(agentIds));
            list.add(agentId);
            agentIds = list.toArray(new Long[list.size()]);
        } else {
            agentIds = new Long[]{agentId};
        }
        return agentIds;
    }


    @Override
    public int getCountfrontOrder(Long memberId, Integer frontOrderStatus) {
        return baseMapper.getCountfrontOrder(memberId, OrderFromEnum.MEMBER.getValue(), frontOrderStatus);
    }

    @Override
    public IPage<TransferListVo> byDepotId(Page initMpPage, Long depotId) {
        return baseMapper.byDepotId(initMpPage, depotId);
    }

    @Override
    public List<TransferListVo> byDepotId(Long depotId) {
        return baseMapper.byDepotId(depotId);
    }

    @Override
    public void updateStatus(Integer depotId) {
        baseMapper.updateStatus(depotId);
    }


    @Override
    public Long selectProductId(ProductIdQuery productIdQuery) {
        return orderGoodsService.getProductId(productIdQuery.getProductSkuDesp(), productIdQuery.getGoodsId());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bind(Long id, Long agentId, String remark, Long uid) {
        SysUserEditVo sysUserEditVo = sysConfigService.getUserById(uid).getData();
        //查询代理商信息
        AgentRpcVo agentDetailsVo = agentServiceRpc.selectByAgentId(agentId).getData();
        Order order = new Order();
        order.setId(id);
        order.setAgentId(agentId);
        if (agentDetailsVo != null) {
            order.setAgentName(agentDetailsVo.getAgentName());
            order.setAgentSn(agentDetailsVo.getAgentSn());
            order.setDistributorId(agentDetailsVo.getDealerId());
            order.setDistributorName(agentDetailsVo.getDealer());
        }
        order.setUpdatedTime(new Date());
        //订单表修改信息
        baseMapper.updateById(order);

        //客服操作记录
        OrderOperationDto orderOperationDto = new OrderOperationDto();
        //操作人类型为客服 2
        orderOperationDto.setOperatorType(OperateTypeEnum.EDIT);
        //操作人id
        orderOperationDto.setOperatorId(uid);
        if (sysUserEditVo != null) {
            //操作人
            orderOperationDto.setOperator(sysUserEditVo.getRealName());
        }
        //订单id
        orderOperationDto.setOrderId(id);
        //操作备注
        orderOperationDto.setRemark(remark);
        //操作内容
        orderOperationDto.setOperation("秒杀活动绑定代理商");
        orderOperationService.save(orderOperationDto);
    }

    @Override
    public IndexOrderReportVo getAdminIndexOrderReport() {
        IndexOrderReportVo ior = new IndexOrderReportVo();
        // 今日订单总数
        Integer totalOrders = 0;
        // 今日订单发货总数
        Integer shipmentsTotalOrders = 0;
        // 今日订单退货总数
        Integer returnTotalOrders = 0;
        // 今日订单断货总数
        Integer outStockTotalOrders = 0;
        // 今日订单换货总数
        Integer changeTotalOrders = 0;

        List<Order> orderList = baseMapper.selectList(new LambdaQueryWrapper<Order>().likeRight(Order::getCreatedTime, DateUtil.today()));
        totalOrders = orderList.size();
        for (Order order : orderList) {
            if (OrderStateEnum.SHIPED.getValue().equals(order.getOrderStatus())) {
                shipmentsTotalOrders += 1;
            }
            if (order.getItemStatus() != null && ProductStatusEnum.STATUS6.getValue().equals(order.getItemStatus())) {
                outStockTotalOrders += 1;
            }
        }
        //退货总数
        List<AfterSale> afterSaleList = afterSaleService.list(new LambdaQueryWrapper<AfterSale>().likeRight(AfterSale::getCreatedTime, DateUtil.today()));
        for (AfterSale as : afterSaleList) {
            if (as.getAfterSaleType() != null && AfterSalesTypeEnum.RETURN_GOODS.getValue().equals(as.getAfterSaleType())) {
                returnTotalOrders += 1;
            } else if (as.getAfterSaleType() != null && AfterSalesTypeEnum.EXCHANE_GOODS.getValue().equals(as.getAfterSaleType())) {
                changeTotalOrders += 1;
            }
        }
        ior.setTotalOrders(totalOrders);
        ior.setShipmentsTotalOrders(shipmentsTotalOrders);
        ior.setReturnTotalOrders(returnTotalOrders);
        ior.setOutStockTotalOrders(outStockTotalOrders);
        ior.setChangeTotalOrders(changeTotalOrders);
        return ior;
    }

    @Override
    public List<IndexSaleReportVo> getAdminIndexSaleReport(String startTime, String endTime) {
        if (StrUtil.isEmpty(startTime) || StrUtil.isEmpty(endTime)) {
            startTime = DateUtil.formatDate(DateUtil.offsetDay(new DateTime(), -14));//偏移14  默认查询十五天
            endTime = DateUtil.today();
        }
        List<IndexSaleReportVo> indexSaleReportVoList = baseMapper.selectAdminIndexSaleReport(startTime, endTime);
        //填充空缺日期
        List<String> stringList = packgeDate(startTime, endTime);
        stringList.forEach(strDate -> {
            //是否空缺标记
            boolean flag = true;
            for (IndexSaleReportVo isrv : indexSaleReportVoList) {
                if (strDate.equals(isrv.getSaleDate())) {
                    flag = false;
                }
            }
            if (flag) {
                IndexSaleReportVo isrv = new IndexSaleReportVo();
                isrv.setSaleDate(strDate);
                isrv.setSaleTotal(0);
                indexSaleReportVoList.add(isrv);
            }
        });
        //日期排序 正序
        indexSaleReportVoList.sort(Comparator.comparing(IndexSaleReportVo::getSaleDate));
        return indexSaleReportVoList;
    }

    /**
     * 方法描述:   活动订单
     *
     * @param actId
     * @return java.util.List<com.weixing.mall.provider.api.model.vo.ActOrderSettleVo>
     * @Author Small
     * @Date 2020/4/14 10:37
     */
    @Override
    public List<ActOrderSettleVo> selectAgentActOrdersByActId(Long actId) {
        return baseMapper.selectAgentActOrdersByActId(actId);
    }

    private List<String> packgeDate(String startTime, String endTime) {
        //计算相差天数
        String startTimeStr = startTime + " 00:00:00";
        Date startDate = DateUtil.parse(startTimeStr);
        String endTimeStr = endTime + " 23:59:59";
        Date endDate = DateUtil.parse(endTimeStr);
        long betweenDay = DateUtil.between(startDate, endDate, DateUnit.DAY);
        List<String> stringList = Lists.newArrayList();
        for (int i = 0; i <= betweenDay; i++) {
            stringList.add(DateUtil.formatDate(DateUtil.offsetDay(startDate, i)));//偏移
        }
        return stringList;
    }

    @Override
    public void confirmOrder(Long mid, Long orderId) {
        Order order = getById(orderId);
        if (ObjectUtil.isEmpty(order)) {
            throw new BusinessException("订单不存在");
        }
        if (!mid.equals(order.getBuyerId())) {
            throw new BusinessException("非法操作");
        }
        if (!OrderFrontStateEnum.WAIT_RECEIVE.getValue().equals(order.getFrontOrderStatus())) {
            throw new BusinessException("非待收货订单");
        }
        order.setFrontOrderStatus(OrderFrontStateEnum.FINISHED.getValue());
        order.setOrderStatus(OrderStateEnum.FINISHED.getValue());
        order.setSysTag(OrderSysTagEnum.YWC_TAG_110.getValue());
        order.setAppTag(OrderAppTagEnum.YWC_TAG_108.getValue());
        order.setUpdatedTime(new Date());
        updateById(order);
    }

    @Override
    public void autoConfirmOrder() {
        Map map = new HashMap<String, Integer>();
        map.put("updateOrderStatus", OrderStateEnum.FINISHED.getValue());
        map.put("updateFrontOrderStatus", OrderFrontStateEnum.FINISHED.getValue());
        map.put("orderStatus", OrderStateEnum.SHIPED.getValue());
        map.put("frontOrderStatus", OrderFrontStateEnum.WAIT_RECEIVE.getValue());
        map.put("dayNum", GlobalConstant.AUTO_CONFIRM_ORDER_DAY);
        map.put("sysTag", OrderSysTagEnum.YWC_TAG_110.getValue());
        map.put("appTag", OrderAppTagEnum.YWC_TAG_108.getValue());
        baseMapper.autoConfirmOrder(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void executeSeckillOrderImport(List<Order> orderList, List<OrderAgent> orderAgentList) {
        List<Long> orderIds = orderList.stream().map(t -> t.getId()).collect(Collectors.toList());
        orderAgentService.remove(new QueryWrapper<OrderAgent>().in("order_id", orderIds));
        for (Order order : orderList) {
            order.setUpdatedTime(new Date());
        }
        updateBatchById(orderList);
        orderAgentService.saveBatch(orderAgentList);
    }

    @Override
    public Order findByOrderSn(String orderSn) {
        QueryWrapper<Order> wrapper = new QueryWrapper<Order>().eq("order_sn", orderSn);
        return getOne(wrapper);
    }


    @Override
    public void cancelOrder(long orderId) {
        Order order = getById(orderId);
        order.setFrontOrderStatus(OrderFrontStateEnum.CANCELD.getValue());
        order.setOrderStatus(OrderStateEnum.CANCELD.getValue());
        order.setSysTag(OrderSysTagEnum.WXD_TAG_102.getValue());
        order.setUpdatedTime(new Date());
        updateById(order);
    }

    @Override
    public void updateTag(Long orderId, Integer sysTag, Integer appTag) {
        updateById(new Order().setId(orderId).setSysTag(sysTag).setAppTag(appTag).setUpdatedTime(new Date()));
    }

    @Override
    public Map<String, Object> getAgentRuleData(Long agentId, String startTime, String endTime) {
        Map<String, Object> map = new HashMap<>();
        BigDecimal saleAmount = BigDecimal.ZERO;
        Integer saleNum = 0;
        AgentOrderQuery query = new AgentOrderQuery();
        query.setAgentId(agentId);
        query.setStartTime(startTime);
        query.setEndTime(endTime);
        query.setOrderStatus(OrderStateEnum.FINISHED);
        StaticVo resultMap = baseMapper.agentAchievement(query);
        map.put("saleNum", resultMap.getTotalNum() + "");//+"" 防止数字过大转成科学计数法
        map.put("saleAmount", resultMap.getTotalAmount() + "");//+"" 防止数字过大转成科学计数法
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetOrderStatus(Long orderId) {
        Order order = getById(orderId);
        if (ObjectUtil.isEmpty(order)) {
            throw new BusinessException("订单信息不存在！");
        }
        if (order.getNosuppllyAudit() != null && order.getNosuppllyAudit().equals(1)) {
            throw new BusinessException("客服已审核无法重置状态！");
        }
        if (order.getItemStatus() != null
                && !ProductStatusEnum.STATUS6.getValue().equals(order.getItemStatus())
                && !ProductStatusEnum.STATUS7.getValue().equals(order.getItemStatus())) {
            throw new BusinessException("非断货或取消订单无法重置状态！");
        }
        /*order.setOrderStatus(OrderStateEnum.WAIT_SHIP.getValue());
        order.setItemStatus(ProductStatusEnum.STATUS8.getValue());
        order.setSysTag(OrderSysTagEnum.DFH_TAG_108.getValue());
        order.setAppTag(OrderAppTagEnum.DFH_TAG_106.getValue());
        order.setCanceledTime(null);
        updateById(order);*/
        UpdateWrapper uw = new UpdateWrapper();
        uw.eq("id", orderId);
        uw.set("order_status", OrderStateEnum.WAIT_SHIP.getValue());
        uw.set("item_status", ProductStatusEnum.STATUS8.getValue());
        uw.set("sys_tag", OrderSysTagEnum.DFH_TAG_108.getValue());
        uw.set("app_tag", OrderAppTagEnum.DFH_TAG_106.getValue());
        uw.set("canceled_time", null);
        uw.set("updated_time", new Date());
        update(uw);
        orderGoodsService.update(new LambdaUpdateWrapper<OrderGoods>()
                .eq(OrderGoods::getOrderId, orderId)
                .set(OrderGoods::getProductStatus, ProductStatusEnum.STATUS8.getValue()));
    }

    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public void changsCode(Long orderId, Long productId, Boolean flag) {
        Result<ItemVo> result = itemFeign.findById(productId);
        if (!result.isSuccess() || ObjectUtil.isEmpty(result.getData())) {
            throw new BusinessException("商品资源获取失败请重试");
        }
        ItemVo itemVo = result.getData();
        OrderGoodsVo orderGoodsVo = orderGoodsService.findByOrderId(orderId);
        if (ObjectUtil.isEmpty(orderGoodsVo)) {
            throw new BusinessException("订单信息获取失败请重试");
        }
        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setId(orderGoodsVo.getId());
        orderGoods.setProductId(itemVo.getProductId());
        orderGoods.setSkuDesp(itemVo.getProductSkuDesp());
        orderGoods.setGoodsImg(itemVo.getProductImg());
        orderGoods.setGoodsName(itemVo.getProductName());
        orderGoods.setProductSn(itemVo.getProductSn());
        orderGoods.setChagSkuDesp(orderGoodsVo.getSkuDesp());
        orderGoods.setCommodityCode("");
        orderGoodsService.updateById(orderGoods);
        if (flag && ObjectUtil.isNotEmpty(orderGoodsVo.getCommodityCode())) {//解除绑定
            orderBindingService.cancelBindingByOrderIdOrCommodityCode(orderGoodsVo.getCommodityCode(), orderId);
        }
    }
}
